package im.composer.ds;

import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;

import org.tritonus.share.sampled.FloatSampleBuffer;

public class FloatSampleQueue implements Iterable<FloatSampleBuffer>, Iterator<FloatSampleBuffer> {

	private final Deque<FloatSampleBuffer> q = new LinkedList<>();
	private int bufz = 32;

	public int getBuffsize() {
		return bufz;
	}

	public void setBuffsize(int bufz) {
		this.bufz = bufz;
	}

	public boolean offer(FloatSampleBuffer e) {
		if(e==null||e.getSampleCount()<1){
			return false;
		}
		return q.offer(e);
	}

	public void clear() {
		q.clear();
	}

	@Override
	public boolean hasNext() {
		return !q.isEmpty();
	}

	@Override
	public FloatSampleBuffer next() {
		FloatSampleBuffer fsb = q.poll();
		if (fsb == null) {
			return null;
		}
		if (fsb.getSampleCount() == bufz) {
			return fsb;
		} else if (fsb.getSampleCount() > bufz) {
			FloatSampleBuffer buf1 = new FloatSampleBuffer(fsb.getChannelCount(), bufz, fsb.getSampleRate());
			fsb.copyTo(buf1, 0, bufz);
			int len = fsb.getSampleCount() - bufz;
			FloatSampleBuffer buf2 = new FloatSampleBuffer(fsb.getChannelCount(), len, fsb.getSampleRate());
			fsb.copyTo(buf2, bufz, len);
			q.push(buf2);
			return buf1;
		} else {
			q.push(fsb);
			FloatSampleBuffer buf1 = new FloatSampleBuffer(fsb.getChannelCount(), bufz, fsb.getSampleRate());
			int pos = 0;
			while (pos < bufz) {
				fsb = q.poll();
				if (fsb == null) {
					buf1.setSampleCount(pos, true);
					break;
				}
				int count = fsb.getSampleCount();
				if (count + pos <= bufz) {
					fsb.copyTo(buf1, pos, count);
					pos += count;
				} else {
					int len = bufz - pos;
					fsb.copyTo(buf1, pos, len);
					FloatSampleBuffer buf2 = new FloatSampleBuffer(fsb.getChannelCount(), len, fsb.getSampleRate());
					fsb.copyTo(fsb.getSampleCount()-len, buf2, 0, len);
					q.push(buf2);
					pos+=len;
				}
			}
			return buf1;
		}
	}

	@Override
	public Iterator<FloatSampleBuffer> iterator() {
		return this;
	}

}
